<?php
/**
 * Provides access to Document Centre documents.
 */
class DocCentre_Server
{
	/**
	 * Reference to the DocCentre system object.
	 * 
	 * @var DocCentre
	 */
	protected $system;
	
	
	
	/**
	 * Controls access to Document Centre documents.
	 * 
	 * @param DocCentre $system
	 * @return DocCentre_Server
	 */
	public function __construct(DocCentre $system)
	{
		$this->system = $system;
		$this->handle_document_requests();
	}
	
	
	/**
	 * Returns a URL for the specified post to be accessed through.
	 * This does not check if the post is valid or if it is a Document
	 * Centre post.
	 * 
	 * @param int $post_id
	 * @return string
	 */
	public function form_access_url($post_id)
	{
		// Get the base site URL
		$url = trailingslashit(get_bloginfo('siteurl'));
		
		// Enforce HTTPS if required
		$scheme = is_ssl() ? 'https://' : 'http://';
		$scheme = apply_filters('doccentre_server_scheme', $scheme);
		
		if (strpos($url, $scheme) !== 0) $url = str_replace($url, $scheme);
		
		// Create URL query
		$query = array(
			'doccentre' => hash('md5', get_current_user_id().AUTH_SALT),
			'request' => $post_id
		);
		
		$query = http_build_query($query);
		return "$url?$query";
	}
	
	
	/**
	 * Checks for and process document requests.
	 */
	protected function handle_document_requests()
	{
		// Return to normal flow of execution if nothing has been requested
		if (!isset($_GET) or !array_key_exists('doccentre', $_GET) or
			!array_key_exists('request', $_GET))
				return;

		// Wait until WordPress loads before further handling
		add_action('wp_loaded', array($this, 'assess_request'));		
	}
	
	
	/**
	 * Assesses the request and the current user's permissions.
	 */
	public function assess_request()
	{
		// Is the user logged in and do they have "read" permission?
		if (!is_user_logged_in() or !current_user_can('read'))
			return;

		// Security: perform hash check
		if ($_GET['doccentre'] != hash('md5', get_current_user_id().AUTH_SALT))
			return;

		// Return the requested document
		$this->return_document($_GET['request']);
	}
	
	
	/**
	 * Attempts to output the requested document to the user.
	 * 
	 * @todo test if the returned post is valid
	 * @todo best guess content type header
	 * @todo serve document
	 * @todo shutdown
	 * 
	 * @param int $post_id
	 */
	protected function return_document($post_id)
	{
		// Try to load the post object
		$post_id = (int) $post_id;
		$post = get_post($post_id);
		
		// Don't continue if unsuccessful
		if (is_null($post) or is_object($post) === false)
			return;
		
		// Load the media or return
		$media = $this->obtain_media($post->guid);
		if (empty($media)) return;
		
		// Output headers
		header('Content-type: '.$post->post_mime_type);
		header('Content-Disposition: attachment; filename="'.basename($post->guid).'"');
		
		// Output content and die
		die($media);
	}
	
	
	/**
	 * Loads the remote URL and returns the data in a variable.
	 * 
	 * @param string $url
	 * @return mixed
	 */
	protected function obtain_media($url)
	{
		return file_get_contents($url);
	}
} 